package com.test.stream;

import com.sun.org.apache.xpath.internal.operations.Bool;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

//https://blog.csdn.net/qq_21918021/article/details/88824335
public class StreamDemo {
    public static void main(String[] args) {
        List<Person> list=new ArrayList<>();
        list.add(new Person("jack",12));
        list.add(new Person("back",19));
        list.add(new Person("mack",20));
        System.out.println(list.stream().map(p->p.getAge()+10).collect(Collectors.toList()));
        System.out.println(list.stream().peek(p-> p.setAge(p.getAge()+10)).collect(Collectors.toList()));

        /*List<String> nameList=list.stream().map(Person::getName).collect(Collectors.toList());
        List<Integer> intList=list.stream().map(Person::getAge).collect(Collectors.toList());
       // System.out.println(nameList);
       // System.out.println(intList);
        //list=list.stream().filter(person-> person.getAge()==20).collect(Collectors.toList());
        list=list.stream().distinct().collect(Collectors.toList());
        list=list.stream().sorted((p1,p2)->p1.getAge()-p2.getAge()).collect(Collectors.toList());
        list=list.stream().sorted(Comparator.comparingInt(Person::getAge)).collect(Collectors.toList());
        System.out.println(list);


        boolean result=list.stream().anyMatch(person -> person.getAge()==20);
        System.out.println(result);
        result=list.stream().allMatch(person -> person.getAge()==20);
        System.out.println(result);
        result=list.stream().noneMatch(person -> person.getAge()==20);
        System.out.println(result);

        System.out.println(list.stream().findFirst());
        //使用 stream() 时找到的是第一个元素
        System.out.println(list.stream().findAny());
        //使用 parallelStream() 时找到的是其中一个元素
        System.out.println(list.parallelStream().findAny());
*/

//        System.out.println(list.stream().count());
//        System.out.println(list.stream().mapToInt(Person::getAge).sum());
//        System.out.println(list.stream().map(Person::getAge).reduce(Integer::sum).get());


       // testIntegerSort();
       // testFlatmap();
       // testReduce();
       // testEach();
      //  testNum();
     //   testFunc();
      //  testJoin();
//        testGroup();
      //  testPartition();
    }

    //数字排序
    public static void testIntegerSort(){
        List<Integer> list= Arrays.asList(2,1,5,4,0);
        System.out.println(list);
        list.sort((a,b)->a-b);
        System.out.println(list);
        list.sort((a,b)->a.compareTo(b.intValue()));
        System.out.println(list);
        System.out.println(list.stream().skip(3).limit(1).collect(Collectors.toList()));
        System.out.println(list.stream().limit(3).skip(1).collect(Collectors.toList()));


    }
    //flatmap
    public static void testFlatmap(){
        List<String> list = new ArrayList<>();
        list.add("aaa bbb ccc");
        list.add("ddd eee fff");
        list.add("ggg hhh iii");
        System.out.println(list);
        System.out.println(list.stream().map(s -> s.split(" ")).collect(Collectors.toList()));
        list=list.stream().map(s->s.split(" ")).flatMap(Arrays::stream).collect(Collectors.toList());
        System.out.println(list);
    }

    //归约 reduce
    public static void testReduce(){
        List<Person> list=new ArrayList<>();
        list.add(new Person("jack",12));
        list.add(new Person("back",19));
        list.add(new Person("mack",20));
        System.out.println(list.stream().map(Person::getAge).reduce(0, Integer::sum));
        System.out.println(list.stream().map(Person::getAge).reduce(0,Integer::max));
        System.out.println(list.stream().mapToInt(Person::getAge).max().getAsInt());
        System.out.println(list.stream().map(Person::getAge).reduce(Integer::max).get());

        System.out.println((long) list.size());
    }

    //foreach
    public static void testEach(){
        List<Person> list=new ArrayList<>();
        list.add(new Person("jack",12));
        list.add(new Person("back",19));
        list.add(new Person("mack",20));
        list.forEach(System.out::println);
    }
    //数值流
    public static void testNum(){
        List<Person> list=new ArrayList<>();
        list.add(new Person("jack",12));
        list.add(new Person("back",19));
        list.add(new Person("mack",20));
        System.out.println(list.stream().mapToInt(Person::getAge).max());
        System.out.println(list.stream().mapToInt(Person::getAge).sum());
        System.out.println(list.stream().mapToInt(Person::getAge).average());
        System.out.println(IntStream.range(0,100).sum());
        System.out.println(IntStream.rangeClosed(0,100).sum());
        System.out.println(Stream.iterate(1,i->i+1).limit(100).reduce(0,Integer::sum));

    }

    //文件生成流

    public static void testFile() {
        try {
            Stream<String> stream =Files.lines(Paths.get("D://a.txt"));
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //函数生成流
    public static void testFunc(){
        System.out.println(Stream.iterate(0,n->n+2).limit(3).collect(Collectors.toList()));
        System.out.println(Stream.generate(Math::random).limit(2).collect(Collectors.toList()));
        System.out.println(Stream.generate(()->1).limit(10).reduce(Integer::sum).get());
    }

    //joining
    public static void testJoin(){
        List<Person> list=new ArrayList<>();
        list.add(new Person("jack",12));
        list.add(new Person("back",19));
        list.add(new Person("mack",20));
        String s=list.stream().map(Person::getName).collect(Collectors.joining());
        System.out.println(s);
        System.out.println(list.stream().map(Person::getName).collect(Collectors.joining(",")));
        System.out.println(list.stream().map(Person::getName).collect(Collectors.joining(" and ","today "," play")));

    }

    //groupingby

    public static void testGroup(){
        List<Person> list=new ArrayList<>();
        list.add(new Person("jack",20));
        list.add(new Person("back",20));
        list.add(new Person("mack",50));
        Map<Integer,List<Person>> map=list.stream().collect(Collectors.groupingBy(Person::getAge));
        System.out.println(map);

        Map<String,List<Person>> result=list.stream().collect(Collectors.groupingBy(person -> {
            if(person.getAge()>60){
                return "老年人";
            }else if(person.getAge()>40){
                return "中年人";
            }else{
                return "青年人";
            }
        }));
        System.out.println(result);

        //多级分组
        Map<Integer,Integer> intMap=list.stream().collect(Collectors.groupingBy(Person::getAge,Collectors.summingInt(Person::getAge)));
        System.out.println(intMap);

    }

    //partitionby 分区

    public static void testPartition(){
        List<Person> list=new ArrayList<>();
        list.add(new Person("jack",20));
        list.add(new Person("back",20));
        list.add(new Person("mack",50));
        Map<Boolean,List<Person>> map=list.stream().collect(Collectors.partitioningBy(p->p.getAge()>40));
        System.out.println(map);

    }

}
